{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Tce3stUlHN0L"
      },
      "source": [
        "##### Copyright 2020 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "tuOe1ymfHZPu"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qFdPvlXBOdUN"
      },
      "source": [
        "# Знакомство с тюнером Keras(Keras Tuner)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MfBg1C5NB3X0"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/keras_tuner\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />Смотрите на TensorFlow.org</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ru/tutorials/keras/keras_tuner.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Запустите в Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/ru/tutorials/keras/keras_tuner.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />Изучайте код на GitHub</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ru/tutorials/keras/keras_tuner.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Скачайте ноутбук</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8a2322303a3f"
      },
      "source": [
        "Note: Вся информация в этом разделе переведена с помощью русскоговорящего Tensorflow сообщества на общественных началах. Поскольку этот перевод не является официальным, мы не гарантируем что он на 100% аккуратен и соответствует [официальной документации на английском языке](https://www.tensorflow.org/?hl=en). Если у вас есть предложение как исправить этот перевод, мы будем очень рады увидеть pull request в [tensorflow/docs](https://github.com/tensorflow/docs) репозиторий GitHub. Если вы хотите помочь сделать документацию по Tensorflow лучше (сделать сам перевод или проверить перевод подготовленный кем-то другим), напишите нам на [docs-ru@tensorflow.org list](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ru)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xHxb-dlhMIzW"
      },
      "source": [
        "## Введение\n",
        "\n",
        "Keras Tuner - это библиотека, которая помогает вам выбрать оптимальный набор гиперпараметров для вашей программы TensorFlow. Процесс выбора правильного набора гиперпараметров для вашего приложения машинного обучения (ML) называется *настройкой гиперпараметров* или *гипертонастройкой*.\n",
        "\n",
        "Гиперпараметры - это переменные, которые управляют процессом обучения и топологией модели машинного обучения. Эти переменные остаются постоянными в процессе обучения и напрямую влияют на эффективность вашей модели. Гиперпараметры бывают двух типов:\n",
        "1. **Гиперпараметры модели**, которые влияют на установки модели, такие как количество и глубина скрытых слоев.\n",
        "2. **Гиперпараметры алгоритма**, которые влияют на скорость и качество алгоритма обучения, такие как скорость обучения для стохастического градиентного спуска (SGD) или количество ближайших соседей для классификатора k Nearest Neighbors(KNN).\n",
        "\n",
        "В этом руководстве вы будете использовать Keras Tuner для выполнения гипертонастройки модели классификации изображений."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MUXex9ctTuDB"
      },
      "source": [
        "## Установка"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "IqR2PQG4ZaZ0"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf\n",
        "from tensorflow import keras\n",
        "\n",
        "import IPython"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "g83Lwsy-Aq2_"
      },
      "source": [
        "Установка и импорт Keras Tuner."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_leAIdFKAxAD"
      },
      "outputs": [],
      "source": [
        "!pip install -U keras-tuner\n",
        "import kerastuner as kt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ReV_UXOgCZvx"
      },
      "source": [
        "## Загрузка и подготовка датасета\n",
        "\n",
        "В этом руководстве вы будете использовать Keras Tuner, чтобы найти лучшие гиперпараметры для модели машинного обучения, которая классифицирует изображения одежды из [набора данных Fashion MNIST](https://github.com/zalandoresearch/fashion-mnist). "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HljH_ENLEdHa"
      },
      "source": [
        "Загружаем данные."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OHlHs9Wj_PUM"
      },
      "outputs": [],
      "source": [
        "(img_train, label_train), (img_test, label_test) = keras.datasets.fashion_mnist.load_data()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "bLVhXs3xrUD0"
      },
      "outputs": [],
      "source": [
        "# Нормализуем пиксели в значения между 0 и 1\n",
        "img_train = img_train.astype('float32') / 255.0\n",
        "img_test = img_test.astype('float32') / 255.0"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K5YEL2H2Ax3e"
      },
      "source": [
        "## Определение модели\n",
        "\n",
        "При построении модели для гипертонастройки вы также определяете пространство поиска гиперпараметров в дополнение к архитектуре модели. Модель, которую вы настроили для гипертюнинга, называется *гипермоделью *.\n",
        "\n",
        "Вы можете определить гипермодель двумя способами:\n",
        "\n",
        "* Используя функцию построителя модели\n",
        "* Создав подкласс класса HyperModel из Keras Tuner API\n",
        "\n",
        "Вы можете использовать два предопределенных класса HyperModel - [HyperXception](https://keras-team.github.io/keras-tuner/documentation/hypermodels/#hyperxception-class) и [HyperResNet](https://keras-team.github.io/keras-tuner/documentation/hypermodels/#hyperresnet-class) для приложений компьютерного зрения.\n",
        "\n",
        "В этом руководстве вы будете использовать функцию построителя моделей для определения модели классификации изображений. Функция построителя моделей возвращает скомпилированную модель и использует гиперпараметры, которые вы определяете во время вызова функции."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ZQKodC-jtsva"
      },
      "outputs": [],
      "source": [
        "def model_builder(hp):\n",
        "  model = keras.Sequential()\n",
        "  model.add(keras.layers.Flatten(input_shape=(28, 28)))\n",
        "  \n",
        "  # Настраиваем кол-во юнитов в первом слое Dense\n",
        "  # Выбираем оптимальное значение между 32-512\n",
        "  hp_units = hp.Int('units', min_value = 32, max_value = 512, step = 32)\n",
        "  model.add(keras.layers.Dense(units = hp_units, activation = 'relu'))\n",
        "  model.add(keras.layers.Dense(10))\n",
        "\n",
        "  # Настраиваем learning rate для оптимайзера\n",
        "  # Выбираем оптимальное значение из 0.01, 0.001, или 0.0001\n",
        "  hp_learning_rate = hp.Choice('learning_rate', values = [1e-2, 1e-3, 1e-4]) \n",
        "  \n",
        "  model.compile(optimizer = keras.optimizers.Adam(learning_rate = hp_learning_rate),\n",
        "                loss = keras.losses.SparseCategoricalCrossentropy(from_logits = True), \n",
        "                metrics = ['accuracy'])\n",
        "  \n",
        "  return model"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0J1VYw4q3x0b"
      },
      "source": [
        "## Создание экземпляра тюнера и гипертюнинг\n",
        "\n",
        "Создайте экземпляр тюнера для выполнения гипертонастройки. Тюнер Keras имеет четыре доступных тюнера - RandomSearch, Hyperband, BayesianOptimization и Sklearn. В этом руководстве вы будете использовать тюнер [Hyperband](https://arxiv.org/pdf/1603.06560.pdf).\n",
        "\n",
        "Чтобы создать экземпляр тюнера Hyperband, вы должны указать гипермодель, `objective`(метрику, на которую будет ориентироваться модель) для оптимизации и максимальное количество эпох для обучения (`max_epochs`)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "oichQFly6Y46"
      },
      "outputs": [],
      "source": [
        "tuner = kt.Hyperband(model_builder,\n",
        "                     objective = 'val_accuracy', \n",
        "                     max_epochs = 10,\n",
        "                     factor = 3,\n",
        "                     directory = 'my_dir',\n",
        "                     project_name = 'intro_to_kt')                       "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VaIhhdKf9VtI"
      },
      "source": [
        "Алгоритм настройки Hyperband использует адаптивное распределение ресурсов и раннюю остановку, чтобы быстро перейти к высокопроизводительной модели. Это делается по подобию сетки спортивного чемпионата. Алгоритм обучает большое количество моделей в течение нескольких эпох и переносит на следующий этап только половину наиболее эффективных моделей. Hyperband определяет количество моделей для обучения в группе, вычисляя 1 + log<sub>`factor`</sub> (`max_epochs`) и округляя его до ближайшего целого числа."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oTeamrUWOJRb"
      },
      "source": [
        "Перед запуском поиска по гиперпараметрам определите ф-цию обратного вызова для очистки результатов обучения в конце каждого шага обучения."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Bbr_8QE76PJd"
      },
      "outputs": [],
      "source": [
        "class ClearTrainingOutput(tf.keras.callbacks.Callback):\n",
        "  def on_train_end(*args, **kwargs):\n",
        "    IPython.display.clear_output(wait = True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UKghEo15Tduy"
      },
      "source": [
        "Запустите поиск гиперпараметров. Аргументы для метода поиска те же, что и для `tf.keras.model.fit` плюс колбек, определенный выше."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dSBQcTHF9cKt"
      },
      "outputs": [],
      "source": [
        "tuner.search(img_train, label_train, epochs = 10, validation_data = (img_test, label_test), \n",
        "             callbacks = [ClearTrainingOutput()])\n",
        "\n",
        "# Получаем оптимальные гиперпараметры\n",
        "best_hps = tuner.get_best_hyperparameters(num_trials = 1)[0]\n",
        "\n",
        "print(f\"\"\"\n",
        "The hyperparameter search is complete. The optimal number of units in the first densely-connected\n",
        "layer is {best_hps.get('units')} and the optimal learning rate for the optimizer\n",
        "is {best_hps.get('learning_rate')}.\n",
        "\"\"\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Lak_ylf88xBv"
      },
      "source": [
        "Чтобы завершить это руководство, переобучите модель с оптимальными гиперпараметрами из поиска."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "McO82AXOuxXh"
      },
      "outputs": [],
      "source": [
        "# Строим модель с оптимальными гиперпараметрами и обучим ее на данных\n",
        "model = tuner.hypermodel.build(best_hps)\n",
        "model.fit(img_train, label_train, epochs = 10, validation_data = (img_test, label_test))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EQRpPHZsz-eC"
      },
      "source": [
        "Каталог `my_dir/intro_to_kt` содержит подробные логи и контрольные точки для каждого испытания(конфигурации модели), запущенного во время поиска гиперпараметров. Если вы повторно запустите поиск гиперпараметров, Keras Tuner использует существующее состояние из этих журналов для возобновления поиска. Чтобы отключить это поведение, передайте дополнительный аргумент `overwrite = True` при создании экземпляра тюнера."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sKwLOzKpFGAj"
      },
      "source": [
        "## Заключение\n",
        "\n",
        "В этом руководстве вы узнали, как использовать Keras Tuner для настройки гиперпараметров модели. Чтобы узнать больше о Keras Tuner, ознакомьтесь с этими дополнительными ресурсами:\n",
        "\n",
        "* [Keras Tuner в блоге TensorFlow](https://blog.tensorflow.org/2020/01/hyperparameter-tuning-with-keras-tuner.html)\n",
        "* [Веб-сайт Keras Tuner](https://keras-team.github.io/keras-tuner/)\n",
        "\n",
        "Также посетите [Панель инструментов HParams](https://www.tensorflow.org/tensorboard/hyperparameter_tuning_with_hparams) в TensorBoard, чтобы интерактивно настроить гиперпараметры вашей модели."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [
        "Tce3stUlHN0L"
      ],
      "name": "keras_tuner.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
